﻿

Public Class PanelZipDesigner

#Region "Fields"
    'Privates :
    Private _FilesList As List(Of String)
    Private _RequestedAction As DesignAction
    Private WithEvents _DesignWorker As BackgroundWorker
    'Publics :
    Private _ImagesList As ImageList
    Public ReadOnly Property ImagesList As ImageList
        Get
            Return _ImagesList
        End Get
    End Property
    Private _SelectedNode As KryptonTreeNode
    Public ReadOnly Property SelectedNode As KryptonTreeNode
        Get
            Return _SelectedNode
        End Get
    End Property
    Private _RootZipNode As ZipNode
    Public ReadOnly Property RootZipNode As ZipNode
        Get
            Return _RootZipNode
        End Get
    End Property
    Private _VisualState As DesignerVisualState
    Public ReadOnly Property VisualState As DesignerVisualState
        Get
            Return _VisualState
        End Get
    End Property
    'Events :
    Public Event NodeSelected As EventHandler(Of NodeSelectedEventArgs)
    Public Event RootZipNodeCreated As EventHandler(Of RootZipNodeCreatedEventArgs)
    Public Event RootZipNodeRenamed As EventHandler(Of RootZipNodeRenamedEventArgs)
    Public Event RootZipNodeDeleted As EventHandler(Of EventArgs)
    Public Event ZipCreationRequested As EventHandler(Of ZipCreationRequestedEventArgs)
#End Region
#Region "Initials"
    Public Sub New()
        Me.InitializeComponent()
        Control.CheckForIllegalCrossThreadCalls = False
        InitializeDesign()
    End Sub
    Private Sub ZipDesigner_Load(sender As Object, e As System.EventArgs) Handles MyBase.Load
        SetVisualState(DesignerVisualState.Initial)
    End Sub
    Private Sub ZipDesigner_Disposed(sender As Object, e As System.EventArgs) Handles MyBase.Disposed
        DisposeDesign()
    End Sub
    Private Sub InitializeDesign()
        _FilesList = New List(Of String)
        _ImagesList = New ImageList With {.ImageSize = New Size(18, 18), .ColorDepth = ColorDepth.Depth32Bit}
        _ImagesList.Images.Add("simplezip", My.Resources.Img_SimpleZip)
        _ImagesList.Images.Add("splitzip", My.Resources.Img_SplitZip)
        _ImagesList.Images.Add("sfxzip", My.Resources.Img_SfxZip)
        _ImagesList.Images.Add("folder", My.Resources.Img_Folder)
        _ImagesList.Images.Add("", My.Resources.Img_NoExt)
        _ImagesList.Images.Add(".exe", My.Resources.Img_Exe)
        _ImagesList.Images.Add(".ico", My.Resources.Img_Ico)
        _ImagesList.Images.Add(".lnk", My.Resources.Img_Lnk)
        ZipTreeView.ImageList = _ImagesList
        _DesignWorker = New BackgroundWorker With {.WorkerReportsProgress = True, .WorkerSupportsCancellation = True}
    End Sub
    Private Sub DisposeDesign()
        _FilesList.Clear()
        _FilesList = Nothing
        _ImagesList.Images.Clear()
        _ImagesList.Dispose()
        _ImagesList = Nothing
        _DesignWorker.Dispose()
        _DesignWorker = Nothing
    End Sub
#End Region
#Region "Dialog"
    Private Sub ShowActionDialog()
        Me.SuspendLayout()
        ZipTreeView.Enabled = False
        Select Case _RequestedAction
            Case DesignAction.Delete
                KHG_Dialog.ValuesPrimary.Image = My.Resources.Img_Remove
                KHG_Dialog.ValuesPrimary.Heading = "Delete This Item ?"
            Case DesignAction.Clear
                KHG_Dialog.ValuesPrimary.Image = My.Resources.Img_Clear
                KHG_Dialog.ValuesPrimary.Heading = "Clear This Item ?"
            Case DesignAction.Clean
                KHG_Dialog.ValuesPrimary.Image = My.Resources.Img_Clean
                KHG_Dialog.ValuesPrimary.Heading = "Clean This Item ?"
        End Select
        KHG_Dialog.ValuesSecondary.Image = _ImagesList.Images.Item(_SelectedNode.ImageKey)
        KHG_Dialog.ValuesSecondary.Heading = _SelectedNode.Text
        KHG_Dialog.Visible = True
        My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Question)
        Me.ResumeLayout()
    End Sub
    Private Sub HideActionDialog()
        Me.SuspendLayout()
        KHG_Dialog.Visible = False
        Me.ResumeLayout()
    End Sub
    Private Sub BSHG_DialogAccept_Click(sender As System.Object, e As System.EventArgs) Handles BSHG_DialogAccept.Click
        Select Case _RequestedAction
            Case DesignAction.Delete
                _DesignWorker.RunWorkerAsync(New Object() {DesignAction.Delete, _SelectedNode})
            Case DesignAction.Clear
                _DesignWorker.RunWorkerAsync(New Object() {DesignAction.Clear, _SelectedNode})
            Case DesignAction.Clean
                _DesignWorker.RunWorkerAsync(New Object() {DesignAction.Clean, _SelectedNode})
        End Select
        HideActionDialog()
    End Sub
    Private Sub BSHG_DialogCancel_Click(sender As System.Object, e As System.EventArgs) Handles BSHG_DialogCancel.Click
        HideActionDialog()
        SelectNode(_SelectedNode)
    End Sub
#End Region
#Region "Actions"
    'Actions (Selected Node) :
    Public Sub NewZip(ByVal type As ZipType)
        Select Case type
            Case ZipType.SimpleZip
                If _RootZipNode Is Nothing Then
                    _RootZipNode = New ZipNode(ZipType.SimpleZip)
                    _RootZipNode.IsRootZipNode = True
                    ZipTreeView.Nodes.Add(_RootZipNode)
                    SelectNode(_RootZipNode)
                    RaiseEvent RootZipNodeCreated(Me, New RootZipNodeCreatedEventArgs(_RootZipNode))
                Else
                    Dim zn As New ZipNode(type)
                    CType(_SelectedNode, IContainable).AddZipNode(zn)
                End If
            Case ZipType.SplitZip
                If _RootZipNode Is Nothing Then
                    _RootZipNode = New ZipNode(ZipType.SplitZip)
                    _RootZipNode.IsRootZipNode = True
                    ZipTreeView.Nodes.Add(_RootZipNode)
                    SelectNode(_RootZipNode)
                    RaiseEvent RootZipNodeCreated(Me, New RootZipNodeCreatedEventArgs(_RootZipNode))
                Else
                    Dim zn As New ZipNode(type)
                    CType(_SelectedNode, IContainable).AddZipNode(zn)
                End If
            Case ZipType.SfxZip
                If _RootZipNode Is Nothing Then
                    _RootZipNode = New ZipNode(ZipType.SfxZip)
                    _RootZipNode.IsRootZipNode = True
                    ZipTreeView.Nodes.Add(_RootZipNode)
                    SelectNode(_RootZipNode)
                    RaiseEvent RootZipNodeCreated(Me, New RootZipNodeCreatedEventArgs(_RootZipNode))
                Else
                    Dim zn As New ZipNode(type)
                    CType(_SelectedNode, IContainable).AddZipNode(zn)
                End If
        End Select
    End Sub
    Public Sub ConvertZip(ByVal type As ZipType)
        CType(_SelectedNode, ZipNode).Type = type
        SelectNode(_SelectedNode)
    End Sub
    Public Sub NewFolder()
        Dim fn As New FolderNode
        CType(_SelectedNode, IContainable).AddFolderNode(fn)
    End Sub
    Public Sub ImportFiles(ByVal filespaths As String())
        ZipTreeView.Enabled = False
        _DesignWorker.RunWorkerAsync(New Object() {DesignAction.ImportFiles, _SelectedNode, filespaths})
    End Sub
    Public Sub ImportFolder(ByVal folderpath As String)
        ZipTreeView.Enabled = False
        _DesignWorker.RunWorkerAsync(New Object() {DesignAction.ImportFolder, _SelectedNode, folderpath})
    End Sub
    Public Sub Delete()
        ZipTreeView.Enabled = False
        _RequestedAction = DesignAction.Delete
        ShowActionDialog()
    End Sub
    Public Sub Clear()
        ZipTreeView.Enabled = False
        _RequestedAction = DesignAction.Clear
        ShowActionDialog()
    End Sub
    Public Sub Clean()
        ZipTreeView.Enabled = False
        _RequestedAction = DesignAction.Clean
        ShowActionDialog()
    End Sub
    Public Sub SelectNode(ByVal ktn As KryptonTreeNode)
        _IsCreating = False
        ZipTreeView.Enabled = True
        ZipTreeView.SelectedNode = Nothing
        ZipTreeView.SelectedNode = ktn
    End Sub
    'Converters:
    Public Sub ConvertZipToFolder()
        SetVisualState(DesignerVisualState.Suspended)
        Dim parent As KryptonTreeNode = CType(Me.SelectedNode.Parent, KryptonTreeNode)
        Dim zipno As ZipNode = CType(Me.SelectedNode, ZipNode)
        Dim fn As New FolderNode()
        fn.Text = zipno.Text
        For Each fono As FolderNode In zipno.FoldersNodes
            zipno.Nodes.Remove(fono)
            fn.AddFolderNode(fono)
        Next
        For Each zn As ZipNode In zipno.ZipNodes
            zipno.Nodes.Remove(zn)
            fn.AddZipNode(zn)
        Next
        For Each fino As FileNode In zipno.FilesNodes
            zipno.Nodes.Remove(fino)
            fn.AddFileNode(fino)
        Next
        parent.Nodes.Remove(zipno)
        CType(parent, IContainable).AddFolderNode(fn)
        Me.SelectNode(fn)
    End Sub
    Public Sub ConvertFolderToZip(ByVal type As ZipType)
        SetVisualState(DesignerVisualState.Suspended)
        Dim parent As KryptonTreeNode = CType(Me.SelectedNode.Parent, KryptonTreeNode)
        Dim folderno As FolderNode = CType(Me.SelectedNode, FolderNode)
        Dim zino As New ZipNode(type)
        zino.Text = folderno.Text
        For Each fono As FolderNode In folderno.FoldersNodes
            folderno.Nodes.Remove(fono)
            zino.AddFolderNode(fono)
        Next
        For Each zn As ZipNode In folderno.ZipNodes
            folderno.Nodes.Remove(zn)
            zino.AddZipNode(zn)
        Next
        For Each fino As FileNode In folderno.FilesNodes
            folderno.Nodes.Remove(fino)
            zino.AddFileNode(fino)
        Next
        parent.Nodes.Remove(folderno)
        CType(parent, IContainable).AddZipNode(zino)
        Me.SelectNode(zino)
    End Sub
    'Helpers :
    Private Function UpdateFilesList(ByVal filespaths As String()) As String()
        Dim files As New List(Of String)
        For Each f As String In filespaths
            If _FilesList.Contains(f) = False Then
                files.Add(f)
                _FilesList.Add(f)
            End If
        Next
        Return files.ToArray
    End Function
    Private Sub UpdateImagesList(ByVal filespaths As String())
        For Each f As String In filespaths
            Dim key As String = IO.Path.GetExtension(f)
            If _ImagesList.Images.Keys.Contains(key) = False Then
                _ImagesList.Images.Add(key, Icon.ExtractAssociatedIcon(f))
            End If
        Next
    End Sub
    Private Sub CheckNewFolderNode(ByVal fn As FolderNode)
        For Each fino As FileNode In fn.FilesNodes
            If _FilesList.Contains(fino.SourcePath) = False Then
                _FilesList.Add(fino.SourcePath)
                UpdateImagesList({fino.SourcePath})
            Else
                fino.Remove()
                fn.UpdateSize(-1L * fino.Size)
            End If
        Next
        For Each fono As FolderNode In fn.FoldersNodes
            CheckNewFolderNode(fono)
        Next
    End Sub
    'DesignWorker :
    Private Sub _DesignWorker_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles _DesignWorker.DoWork
        Dim args As Object() = CType(e.Argument, Object())
        Dim action As DesignAction = CType(args(0), DesignAction)
        Dim target As KryptonTreeNode = CType(args(1), KryptonTreeNode)
        SetVisualState(DesignerVisualState.Suspended)
        Select Case action
            Case DesignAction.ImportFiles
                Dim filespaths As String() = CType(args(2), String())
                Dim filestoadd As String() = UpdateFilesList(filespaths)
                UpdateImagesList(filestoadd)
                For Each f As String In filestoadd
                    Dim fn As New FileNode(f)
                    _DesignWorker.ReportProgress(0, New Object() {DesignAction.ImportFiles, target, fn})
                Next
                e.Result = target

            Case DesignAction.ImportFolder
                Dim folderpath As String = CType(args(2), String)
                Dim fn As New FolderNode(folderpath)
                CheckNewFolderNode(fn)
                _DesignWorker.ReportProgress(0, New Object() {DesignAction.ImportFolder, target, fn})
                e.Result = target

            Case DesignAction.Delete
                Dim nodetoselect As TreeNode
                If target.NextNode IsNot Nothing Then
                    nodetoselect = target.NextNode
                ElseIf target.PrevNode IsNot Nothing Then
                    nodetoselect = target.PrevNode
                Else
                    nodetoselect = target.Parent
                End If
                If TypeOf target Is FileNode Then
                    Dim path As String = CType(target, FileNode).Delete
                    _FilesList.Remove(path)
                ElseIf TypeOf target Is IContainable Then
                    If Object.ReferenceEquals(_RootZipNode, target) = False Then
                        Dim filestoremove As List(Of String) = CType(target, IContainable).Delete
                        For Each f As String In filestoremove
                            _FilesList.Remove(f)
                        Next
                    Else
                        _RootZipNode.Delete()
                        _RootZipNode = Nothing
                        _FilesList = Nothing
                        _FilesList = New List(Of String)
                        ZipTreeView.Enabled = False
                        RaiseEvent RootZipNodeDeleted(Me, Nothing)
                        SetVisualState(DesignerVisualState.Initial)
                    End If
                End If
                e.Result = nodetoselect
            Case DesignAction.Clear
                Dim filestoremove As List(Of String) = CType(target, IContainable).Clear
                For Each f As String In filestoremove
                    _FilesList.Remove(f)
                Next
                e.Result = target
            Case DesignAction.Clean
                Dim filestoremove As List(Of String) = CType(target, IContainable).Clean
                For Each f As String In filestoremove
                    _FilesList.Remove(f)
                Next
                e.Result = target
        End Select
    End Sub
    Private Sub _DesignWorker_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles _DesignWorker.ProgressChanged
        Dim args As Object() = CType(e.UserState, Object())
        Dim action As DesignAction = CType(args(0), DesignAction)
        Dim target As KryptonTreeNode = CType(args(1), KryptonTreeNode)
        Select Case action
            Case DesignAction.ImportFiles
                Dim fn As FileNode = CType(args(2), FileNode)
                CType(target, IContainable).AddFileNode(fn)
            Case DesignAction.ImportFolder
                Dim fn As FolderNode = CType(args(2), FolderNode)
                CType(target, IContainable).AddFolderNode(fn)
        End Select
    End Sub
    Private Sub _DesignWorker_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles _DesignWorker.RunWorkerCompleted
        SelectNode(CType(e.Result, KryptonTreeNode))
    End Sub
#End Region
#Region "Visuals"
    'Zip Tree View Editing & Selection :
    Private Sub ZipTreeView_BeforeLabelEdit(sender As Object, e As System.Windows.Forms.NodeLabelEditEventArgs) Handles ZipTreeView.BeforeLabelEdit
        If TypeOf e.Node Is FileNode Then
            e.CancelEdit = True
        End If
    End Sub
    Private Sub ZipTreeView_AfterLabelEdit(sender As Object, e As System.Windows.Forms.NodeLabelEditEventArgs) Handles ZipTreeView.AfterLabelEdit
        If Object.ReferenceEquals(_RootZipNode, e.Node) = True Then
            RaiseEvent RootZipNodeRenamed(Me, New RootZipNodeRenamedEventArgs(e.Label))
        End If
    End Sub
    Private Sub ZipTreeView_AfterSelect(sender As Object, e As System.Windows.Forms.TreeViewEventArgs) Handles ZipTreeView.AfterSelect
        If _IsCreating = False AndAlso _DesignWorker.IsBusy = False Then
            ZipTreeView.Enabled = True
            _SelectedNode = CType(e.Node, KryptonTreeNode)
            If TypeOf _SelectedNode Is FileNode Then
                SetVisualState(DesignerVisualState.FileNodeSelected)
            ElseIf TypeOf _SelectedNode Is FolderNode Then
                If CType(_SelectedNode, FolderNode).Size > 0 Then
                    SetVisualState(DesignerVisualState.FolderNodeFullSelected)
                Else
                    SetVisualState(DesignerVisualState.FolderNodeEmptySelected)
                End If
            ElseIf TypeOf _SelectedNode Is ZipNode Then
                If CType(_SelectedNode, ZipNode).IsRootZipNode = True Then
                    If CType(_SelectedNode, ZipNode).Size > 0 Then
                        SetVisualState(DesignerVisualState.ZipFileNodeFullSelected)
                    Else
                        SetVisualState(DesignerVisualState.ZipFileNodeEmptySelected)
                    End If
                Else
                    If CType(_SelectedNode, ZipNode).Size > 0 Then
                        SetVisualState(DesignerVisualState.ZipNodeFullSelected)
                    Else
                        SetVisualState(DesignerVisualState.ZipNodeEmptySelected)
                    End If
                End If
            End If
            RaiseEvent NodeSelected(Me, New NodeSelectedEventArgs(_SelectedNode, _VisualState))
        End If
    End Sub
    'Zip Tree View Drag & Drop : (To Do)
    Private Sub ZipTreeView_ItemDrag(sender As Object, e As System.Windows.Forms.ItemDragEventArgs) Handles ZipTreeView.ItemDrag

    End Sub
    Private Sub ZipTreeView_DragEnter(sender As Object, e As System.Windows.Forms.DragEventArgs) Handles ZipTreeView.DragEnter

    End Sub
    Private Sub ZipTreeView_DragOver(sender As Object, e As System.Windows.Forms.DragEventArgs) Handles ZipTreeView.DragOver

    End Sub
    Private Sub ZipTreeView_DragDrop(sender As Object, e As System.Windows.Forms.DragEventArgs) Handles ZipTreeView.DragDrop

    End Sub
    'States :
    Private _IsCreating As Boolean = False
    Private Sub SetVisualState(ByVal state As DesignerVisualState)
        Me.SuspendLayout()
        _IsCreating = False
        KCM_ConvertZip_Folder.Visible = True
        Select Case state
            Case DesignerVisualState.Initial
                ZipTreeView.Enabled = False
                BSHG_CreateZip.Enabled = ButtonEnabled.False
                BSHG_NewZip.Enabled = ButtonEnabled.True
                BSHG_ConvertZip.Enabled = ButtonEnabled.False
                BSHG_NewFolder.Enabled = ButtonEnabled.False
                BSHG_ImportFolder.Enabled = ButtonEnabled.False
                BSHG_ImportFiles.Enabled = ButtonEnabled.False
                BSHG_Delete.Enabled = ButtonEnabled.False
                BSHG_Clear.Enabled = ButtonEnabled.False
                BSHG_Clean.Enabled = ButtonEnabled.False
            Case DesignerVisualState.Suspended
                ZipTreeView.Enabled = False
                BSHG_CreateZip.Enabled = ButtonEnabled.False
                BSHG_NewZip.Enabled = ButtonEnabled.False
                BSHG_ConvertZip.Enabled = ButtonEnabled.False
                BSHG_NewFolder.Enabled = ButtonEnabled.False
                BSHG_ImportFolder.Enabled = ButtonEnabled.False
                BSHG_ImportFiles.Enabled = ButtonEnabled.False
                BSHG_Delete.Enabled = ButtonEnabled.False
                BSHG_Clear.Enabled = ButtonEnabled.False
                BSHG_Clean.Enabled = ButtonEnabled.False
            Case DesignerVisualState.FileNodeSelected
                ZipTreeView.Enabled = True
                BSHG_CreateZip.Enabled = ButtonEnabled.False
                BSHG_NewZip.Enabled = ButtonEnabled.False
                BSHG_ConvertZip.Enabled = ButtonEnabled.False
                BSHG_NewFolder.Enabled = ButtonEnabled.False
                BSHG_ImportFolder.Enabled = ButtonEnabled.False
                BSHG_ImportFiles.Enabled = ButtonEnabled.False
                BSHG_Delete.Enabled = ButtonEnabled.True
                BSHG_Clear.Enabled = ButtonEnabled.False
                BSHG_Clean.Enabled = ButtonEnabled.False
            Case DesignerVisualState.FolderNodeFullSelected
                ZipTreeView.Enabled = True
                BSHG_CreateZip.Enabled = ButtonEnabled.False
                BSHG_NewZip.Enabled = ButtonEnabled.True
                BSHG_ConvertZip.Enabled = ButtonEnabled.True
                BSHG_NewFolder.Enabled = ButtonEnabled.True
                BSHG_ImportFolder.Enabled = ButtonEnabled.True
                BSHG_ImportFiles.Enabled = ButtonEnabled.True
                BSHG_Delete.Enabled = ButtonEnabled.True
                BSHG_Clear.Enabled = ButtonEnabled.True
                BSHG_Clean.Enabled = ButtonEnabled.True
            Case DesignerVisualState.FolderNodeEmptySelected
                ZipTreeView.Enabled = True
                BSHG_CreateZip.Enabled = ButtonEnabled.False
                BSHG_NewZip.Enabled = ButtonEnabled.True
                BSHG_ConvertZip.Enabled = ButtonEnabled.True
                BSHG_NewFolder.Enabled = ButtonEnabled.True
                BSHG_ImportFolder.Enabled = ButtonEnabled.True
                BSHG_ImportFiles.Enabled = ButtonEnabled.True
                BSHG_Delete.Enabled = ButtonEnabled.True
                BSHG_Clear.Enabled = ButtonEnabled.False
                BSHG_Clean.Enabled = ButtonEnabled.False
            Case DesignerVisualState.ZipNodeFullSelected
                ZipTreeView.Enabled = True
                BSHG_CreateZip.Enabled = ButtonEnabled.False
                BSHG_NewZip.Enabled = ButtonEnabled.True
                BSHG_ConvertZip.Enabled = ButtonEnabled.True
                BSHG_NewFolder.Enabled = ButtonEnabled.True
                BSHG_ImportFolder.Enabled = ButtonEnabled.True
                BSHG_ImportFiles.Enabled = ButtonEnabled.True
                BSHG_Delete.Enabled = ButtonEnabled.True
                BSHG_Clear.Enabled = ButtonEnabled.True
                BSHG_Clean.Enabled = ButtonEnabled.True
            Case DesignerVisualState.ZipNodeEmptySelected
                ZipTreeView.Enabled = True
                BSHG_CreateZip.Enabled = ButtonEnabled.False
                BSHG_NewZip.Enabled = ButtonEnabled.True
                BSHG_ConvertZip.Enabled = ButtonEnabled.True
                BSHG_NewFolder.Enabled = ButtonEnabled.True
                BSHG_ImportFolder.Enabled = ButtonEnabled.True
                BSHG_ImportFiles.Enabled = ButtonEnabled.True
                BSHG_Delete.Enabled = ButtonEnabled.True
                BSHG_Clear.Enabled = ButtonEnabled.False
                BSHG_Clean.Enabled = ButtonEnabled.False
            Case DesignerVisualState.ZipFileNodeFullSelected
                ZipTreeView.Enabled = True
                BSHG_CreateZip.Enabled = ButtonEnabled.True
                BSHG_NewZip.Enabled = ButtonEnabled.True
                BSHG_ConvertZip.Enabled = ButtonEnabled.True
                KCM_ConvertZip_Folder.Visible = False
                BSHG_NewFolder.Enabled = ButtonEnabled.True
                BSHG_ImportFolder.Enabled = ButtonEnabled.True
                BSHG_ImportFiles.Enabled = ButtonEnabled.True
                BSHG_Delete.Enabled = ButtonEnabled.True
                BSHG_Clear.Enabled = ButtonEnabled.True
                BSHG_Clean.Enabled = ButtonEnabled.True
            Case DesignerVisualState.ZipFileNodeEmptySelected
                ZipTreeView.Enabled = True
                BSHG_CreateZip.Enabled = ButtonEnabled.False
                BSHG_NewZip.Enabled = ButtonEnabled.True
                BSHG_ConvertZip.Enabled = ButtonEnabled.True
                KCM_ConvertZip_Folder.Visible = False
                BSHG_NewFolder.Enabled = ButtonEnabled.True
                BSHG_ImportFolder.Enabled = ButtonEnabled.True
                BSHG_ImportFiles.Enabled = ButtonEnabled.True
                BSHG_Delete.Enabled = ButtonEnabled.True
                BSHG_Clear.Enabled = ButtonEnabled.False
                BSHG_Clean.Enabled = ButtonEnabled.False
            Case DesignerVisualState.Creating
                _IsCreating = True
                ZipTreeView.Enabled = True
                BSHG_CreateZip.Enabled = ButtonEnabled.False
                BSHG_NewZip.Enabled = ButtonEnabled.False
                BSHG_ConvertZip.Enabled = ButtonEnabled.False
                BSHG_NewFolder.Enabled = ButtonEnabled.False
                BSHG_ImportFolder.Enabled = ButtonEnabled.False
                BSHG_ImportFiles.Enabled = ButtonEnabled.False
                BSHG_Delete.Enabled = ButtonEnabled.False
                BSHG_Clear.Enabled = ButtonEnabled.False
                BSHG_Clean.Enabled = ButtonEnabled.False
        End Select
        Me.ResumeLayout()
        _VisualState = state
    End Sub
    'Controls :
    Private Sub KCM_NewZip_SimpleZip_Click(sender As Object, e As System.EventArgs) Handles KCM_NewZip_SimpleZip.Click
        Me.NewZip(ZipType.SimpleZip)
    End Sub
    Private Sub KCM_NewZip_SplitZip_Click(sender As Object, e As System.EventArgs) Handles KCM_NewZip_SplitZip.Click
        Me.NewZip(ZipType.SplitZip)
    End Sub
    Private Sub KCM_NewZip_SfxZip_Click(sender As Object, e As System.EventArgs) Handles KCM_NewZip_SfxZip.Click
        Me.NewZip(ZipType.SfxZip)
    End Sub
    Private Sub KCM_ConvertZip_SimpleZip_Click(sender As Object, e As System.EventArgs) Handles KCM_ConvertZip_SimpleZip.Click
        If TypeOf Me.SelectedNode Is ZipNode Then
            Me.ConvertZip(ZipType.SimpleZip)
        ElseIf TypeOf Me.SelectedNode Is FolderNode Then
            Me.ConvertFolderToZip(ZipType.SimpleZip)
        End If
    End Sub
    Private Sub KCM_ConvertZip_SplitZip_Click(sender As Object, e As System.EventArgs) Handles KCM_ConvertZip_SplitZip.Click
        If TypeOf Me.SelectedNode Is ZipNode Then
            Me.ConvertZip(ZipType.SplitZip)
        ElseIf TypeOf Me.SelectedNode Is FolderNode Then
            Me.ConvertFolderToZip(ZipType.SplitZip)
        End If
    End Sub
    Private Sub KCM_ConvertZip_SfxZip_Click(sender As Object, e As System.EventArgs) Handles KCM_ConvertZip_SfxZip.Click
        If TypeOf Me.SelectedNode Is ZipNode Then
            Me.ConvertZip(ZipType.SfxZip)
        ElseIf TypeOf Me.SelectedNode Is FolderNode Then
            Me.ConvertFolderToZip(ZipType.SfxZip)
        End If
    End Sub
    Private Sub KCM_ConvertZip_Folder_Click(sender As System.Object, e As System.EventArgs) Handles KCM_ConvertZip_Folder.Click
        If TypeOf Me.SelectedNode Is ZipNode Then
            Me.ConvertZipToFolder()
        End If
    End Sub
    Private Sub BSHG_NewFolder_Click(sender As System.Object, e As System.EventArgs) Handles BSHG_NewFolder.Click
        Me.NewFolder()
    End Sub
    Private Sub BSHG_ImportFolder_Click(sender As System.Object, e As System.EventArgs) Handles BSHG_ImportFolder.Click
        FBD.RootFolder = Environment.SpecialFolder.Desktop
        FBD.Description = "Zipper" & vbNewLine & "Choose The Folder You Want To Import."
        Dim dr As DialogResult = FBD.ShowDialog
        If dr = DialogResult.OK Then
            Me.ImportFolder(FBD.SelectedPath)
        End If
    End Sub
    Private Sub BSHG_ImportFiles_Click(sender As System.Object, e As System.EventArgs) Handles BSHG_ImportFiles.Click
        Dim dr As DialogResult = OFD.ShowDialog
        If dr = DialogResult.OK Then
            Me.ImportFiles(OFD.FileNames)
        End If
    End Sub
    Private Sub BSHG_Delete_Click(sender As System.Object, e As System.EventArgs) Handles BSHG_Delete.Click
        _RequestedAction = DesignAction.Delete
        ShowActionDialog()
    End Sub
    Private Sub BSHG_Clear_Click(sender As System.Object, e As System.EventArgs) Handles BSHG_Clear.Click
        _RequestedAction = DesignAction.Clear
        ShowActionDialog()
    End Sub
    Private Sub BSHG_Clean_Click(sender As System.Object, e As System.EventArgs) Handles BSHG_Clean.Click
        _RequestedAction = DesignAction.Clean
        ShowActionDialog()
    End Sub
    Private _RootZipLocation As String = ""
    Private Sub BSHG_CreateZip_Click(sender As System.Object, e As System.EventArgs) Handles BSHG_CreateZip.Click
        FBD.RootFolder = Environment.SpecialFolder.Desktop
        FBD.Description = "Zipper" & vbNewLine & "Choose The Location Where To Save Your Zip File."
        Dim dr As DialogResult = FBD.ShowDialog
        If dr = DialogResult.OK Then
            _RootZipLocation = FBD.SelectedPath
            RaiseEvent InnerZipsCreationRequested(Me, Nothing)
        End If
    End Sub
    Public Event InnerZipsCreationRequested As EventHandler(Of EventArgs)
#End Region
#Region "Inner Zip Nodes Creation"
    Private _TempsLocations As List(Of String)
    Public ReadOnly Property TempsLocations As List(Of String)
        Get
            Return _TempsLocations
        End Get
    End Property
    Private _Filters As List(Of Filter)
    Public Sub CreateInnerZips(ByVal filters As List(Of Filter))
        _TempsLocations = New List(Of String)
        _InnersCount = _RootZipNode.InnerZipNodes.Count
        ShowInnerZipsStats()
        _Filters = filters
        SetVisualState(DesignerVisualState.Creating)
        StartReadyInnerZipNodes()
    End Sub
    Private Sub StartReadyInnerZipNodes()
        Dim _inners As List(Of ZipNode) = _RootZipNode.InnerZipNodes
        If _inners.Count > 0 Then
            For Each zn As ZipNode In _inners
                If zn.Maker.CanMakeZip = True Then
                    AddHandler zn.InnerZipNodeCreated, AddressOf SomeInnerZipNodeCreated
                    If zn.Maker.CanMakeZip Then
                        zn.Maker.MakeSaveZip(_Filters)
                        zn.Collapse(False)
                    End If
                End If
            Next
        Else
            RaiseEvent ZipCreationRequested(Me, New ZipCreationRequestedEventArgs(_RootZipNode, _RootZipLocation))
        End If
    End Sub
    Private Sub SomeInnerZipNodeCreated(sender As Object, e As ZipSavingFinishedEventArgs)
        RemoveHandler CType(sender, ZipNode).InnerZipNodeCreated, AddressOf SomeInnerZipNodeCreated
        Dim files As New List(Of String)
        For Each fn As FileNode In e.ReplacementFilesNodes
            files.Add(fn.SourcePath)
        Next
        UpdateImagesList(files.ToArray)
        Dim parent As KryptonTreeNode = CType(CType(sender, ZipNode).Parent, KryptonTreeNode)
        For Each fn As FileNode In e.ReplacementFilesNodes
            CType(parent, IContainable).AddFileNode(fn)
        Next
        _TempsLocations.Add(CType(sender, ZipNode).Maker.TempZipLocation)
        CType(sender, ZipNode).Delete()
        _InnersSaved += 1
        ShowInnerZipsStats()
        StartReadyInnerZipNodes()
    End Sub
    Private _InnersCount As Integer
    Private _InnersSaved As Integer
    Private Sub ShowInnerZipsStats()
        KHG.ValuesPrimary.Description = String.Format("({0} / {1})", _InnersSaved, _InnersCount)
    End Sub
#End Region

End Class

